package com.atguigu.spzx.manager.service.Impl;

import com.atguigu.spzx.manager.helper.MenuHelper;
import com.atguigu.spzx.manager.mapper.SysMenuMapper;
import com.atguigu.spzx.manager.service.SysMenuService;
import com.atguigu.spzx.model.entity.system.SysMenu;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.system.SysMenuVo;
import com.atguigu.spzx.service.exception.GuliException;
import com.atguigu.spzx.utils.AuthContextUtil;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: SysMenuServiceImpl
 * Package: com.atguigu.spzx.manager.service.Impl
 * Description:
 *
 * @Author 刘强
 * @Create 2024/7/3 10:54
 * @Version 1.0
 */
@Service
public class SysMenuServiceImpl implements SysMenuService {
    @Resource
    private SysMenuMapper sysMenuMapper;
    /**
     * 查询所有菜单，以树形结构返回
     * @return
     */
    @Override
    public List<SysMenu> findNodes() {
        List<SysMenu> sysMenuList = sysMenuMapper.findNodes();
        List<SysMenu> sysMenuListTree = MenuHelper.buildTree(sysMenuList);

        return sysMenuListTree;
    }

    /**
     * 添加菜单
     * @param sysMenu
     */
    @Override
    public void save(SysMenu sysMenu) {

        sysMenuMapper.save(sysMenu);
    }

    /**
     * 根据id修改菜单
     * @param sysMenu
     */
    @Override
    public void updateById(SysMenu sysMenu) {
        sysMenuMapper.updateById(sysMenu);
    }

    /**
     * 根据id删除菜单
     *      如果该菜单含有子菜单则删除失败
     * @param id
     */
    @Override
    public void removeById(Long id) {
        Integer count = sysMenuMapper.findChildrenCountById(id);
        if(count > 0){
            throw new GuliException(ResultCodeEnum.NODE_ERROR);
        }
        sysMenuMapper.removeById(id);
    }

    /**
     * 根据用户信息查询菜单 树形
     * @return
     */
    @Override
    public List<SysMenuVo> findUserMenuList() {
        // 1. 获取用户id
        Long userId = AuthContextUtil.get().getId();
        // 2. 根据用户id查询菜单
        List<SysMenu> sysMenuList = sysMenuMapper.findUserMenuListById(userId);
        // 2.5 菜单去重 因为不同的角色可能具有相同的菜单，所以我们需要进行菜单去重
        //      去除重复id的菜单
        HashMap<Long, SysMenu> sysMenuMap = new HashMap<>();
        for (SysMenu sysMenu : sysMenuList) {
            sysMenuMap.putIfAbsent(sysMenu.getId(),sysMenu);
        }
        sysMenuList = new ArrayList<>(sysMenuMap.values());
        // 3. 将菜单封装成树
        List<SysMenu> sysMenuListTree = MenuHelper.buildTree(sysMenuList);
        if(CollectionUtils.isEmpty(sysMenuList)){
            return null;
        }
        List<SysMenuVo> sysMenuVoListTree = menuList2MenoVoList(sysMenuListTree);
        return sysMenuVoListTree;
    }

    /**
     * 将SysMenuList 转换为 SysMenuVoList
     * @param sysMenuListTree
     * @return
     */
    private static List<SysMenuVo> menuList2MenoVoList(List<SysMenu> sysMenuListTree) {
        // 递归结束条件返回
        if(CollectionUtils.isEmpty(sysMenuListTree)){
            return null;
        }
        List<SysMenuVo> sysMenuVoListTree = sysMenuListTree.stream().map(ele -> {
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setTitle(ele.getTitle());
            sysMenuVo.setName(ele.getComponent());
            // children属性也需要进行 menu2MenoVo 转换 ---> 递归
            List<SysMenu> children = ele.getChildren();
            if(CollectionUtils.isEmpty(children)){
                sysMenuVo.setChildren(null);
            }
            sysMenuVo.setChildren(menuList2MenoVoList(children));
            return sysMenuVo;
        }).collect(Collectors.toList());
        return sysMenuVoListTree;
    }

}
